package com.dullong.firedocmanager.service;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.dullong.firedocmanager.JODConverter.Converter;
import com.dullong.firedocmanager.bean.PageBean;
import com.dullong.firedocmanager.itext.PDFReader;

import com.dullong.firedocmanager.lucene4.Searchable;
import com.dullong.firedocmanager.lucene4.DocumentCreater;
import com.dullong.firedocmanager.lucene4.LuceneIndexService;
import com.dullong.firedocmanager.lucene4.domain.LDocument;
import com.dullong.firedocmanager.util.ConnectionUtil;
import com.dullong.firedocmanager.util.OptionUtil;

@Service
public class DocumentServiceSupport implements DocumentService {

	@Autowired
	PDFReader pdfReader;
	@Autowired
	Converter converter;
	@Autowired
	LuceneIndexService luceneIndexService;

	@Override
	public boolean parserBody(Long docID) {
		if (!isConvert(docID)) {
			if (!convert(docID)) {
				return false;
			}
		}
		Connection conn = ConnectionUtil.getConnection();
		QueryRunner runner = new QueryRunner();

		try {
			String obj = runner.query(conn,
					"select dir from doc_dir where ID=? and type='pdf'",
					new ScalarHandler<String>(), docID);
			if (obj != null) {
				String option = OptionUtil.getOption("opload_filePath");
				String path = option + File.separator + obj;
				Map<String, Object> pdfFileText = pdfReader
						.getPdfFileText(path);
				runner.update(conn,
						"update document set body=?,page=? where id=?",
						pdfFileText.get("body"),
						Integer.parseInt(pdfFileText.get("page").toString()),
						docID);
				return true;

			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}
		return false;

	}

	@Override
	public boolean alterTitle(Long docId, String title, Integer cate) {

		Connection conn = ConnectionUtil.getConnection();
		QueryRunner runner = new QueryRunner();
		try {
			int i = 0;
			if (title != null && !"".equals(title))
				i = runner.update(conn,
						"update document set title=? where id=?", title, docId);
			if (cate != null)
				i = runner.update(conn,
						"update document set cate=? where id=?", cate, docId);
			if (i > 0)
				return true;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}

		return false;
	}

	@Override
	public void parserAll() {
		List<Long> allNeedParse = getAllNeedParse();
		if (allNeedParse != null)
			for (Object docid : allNeedParse) {
				parserBody((Long) docid);
			}
	}

	@Override
	public boolean shenhe(Integer zhuangtai, Long... docIds) {
		Connection conn = ConnectionUtil.getConnection();
		QueryRunner runner = new QueryRunner();
		try {
			int i = 0;
			for (Long docid : docIds)
				i += runner.update(conn,
						"update document set shenhe=? where id=?", zhuangtai,
						docid);
			if (i > 0)
				return true;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}

		return false;

	}

	@Override
	public void indexDoc(Long... docIds) {

		List<LDocument> docs = DocumentCreater.creatDoc(docIds);
		if (!docs.isEmpty()) {
			try {
				luceneIndexService.add(docs);
				setIndexed(1, docIds);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	void setIndexed(Integer zhuangtai, Long... docIds) {
		Connection conn = ConnectionUtil.getConnection();
		QueryRunner runner = new QueryRunner();
		try {
			int i = 0;
			for (Long docid : docIds)
				i += runner.update(conn,
						"update document set indexed=? where id=?", zhuangtai,
						docid);

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}
	}

	@Override
	public void indexAll() throws SQLException, IOException,
			ClassNotFoundException {
		parserAll();
		Connection conn = ConnectionUtil.getConnection();
		QueryRunner runner = new QueryRunner();
		List<LDocument> list = runner.query(conn,
				"select * from document where indexed=0 and body is not null",
				new BeanListHandler<LDocument>(LDocument.class));
		luceneIndexService.add(list);
		luceneIndexService.optimize();
		runner.update(conn,
				"update document set indexed=1 where body is not null");
		DbUtils.closeQuietly(conn);
	}

	@Override
	public boolean delete(Long... docIds) {
		Connection conn = ConnectionUtil.getConnection();
		QueryRunner runner = new QueryRunner();
		try {
			int i = 0;
			for (Long docid : docIds) {
				i += runner.update(conn, "delete from document where id=?",
						docid);
				i += runner.update(conn, "delete from doc_dir where id=?",
						docid);
			}
			if (i > 0) {
				try {
					luceneIndexService.delete(docIds);
					return true;
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}

		return false;

	}

	@Override
	public boolean isIndex(Long docId) {
		Connection conn = ConnectionUtil.getConnection();
		QueryRunner runner = new QueryRunner();
		try {
			Object[] obj = runner.query(conn,
					"select indexed from document where id=?",
					new ArrayHandler(), docId);
			if (obj == null || obj.length != 1)
				return false;
			Integer indexed = (Integer) obj[0];
			if (indexed != null && indexed == 1)
				return true;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}

		return false;
	}

	@Override
	public List<Long> getAllNeedParse() {
		Connection conn = ConnectionUtil.getConnection();
		QueryRunner runner = new QueryRunner();
		try {
			List<Long> colList = runner.query(conn,
					"select id from document where body is null",
					new ColumnListHandler<Long>());
			return colList;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}

		return null;
	}

	@Override
	public String getDownUrl(Long docid, String type) {
		Connection conn = ConnectionUtil.getConnection();
		QueryRunner runner = new QueryRunner();
		String docurl = null;
		try {
			Object[] objects = runner.query(conn,
					"select dir from  doc_dir where `id`=? and `type`=?",
					new ArrayHandler(), docid, type);
			docurl = objects[0].toString();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}
		return docurl;
	}

	@Override
	public void indexPptimize(Class<? extends Searchable> obj) {

		try {
			luceneIndexService.optimize();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	@Override
	public com.dullong.firedocmanager.bean.Document get(Long ID) {
		Connection conn = ConnectionUtil.getConnection();
		QueryRunner runner = new QueryRunner();
		try {
			@SuppressWarnings("unchecked")
			com.dullong.firedocmanager.bean.Document d = (com.dullong.firedocmanager.bean.Document) runner
					.query(conn,
							"select * from document where id=?",
							new BeanHandler<com.dullong.firedocmanager.bean.Document>(
									com.dullong.firedocmanager.bean.Document.class),
							ID);
			String body = null;
			if (d != null) {
				body = d.getBody();
				if (body != null && body.length() > 100) {
					body = body.substring(0, 100);
					body.replace(" ", "");
				}
				d.setBody(body);
			}

			return d;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}
		return null;
	}

	@Override
	public List<com.dullong.firedocmanager.bean.Document> listAll(Long page,
			Long pnum, String searchword) {
		Connection conn = ConnectionUtil.getConnection();
		QueryRunner runner = new QueryRunner();
		try {
			return runner
					.query(conn,
							"select * from document where title like ? limit ?,?",
							new BeanListHandler<com.dullong.firedocmanager.bean.Document>(
									com.dullong.firedocmanager.bean.Document.class),
							"%" + searchword + "%", (page - 1) * pnum, pnum);

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}
		return null;
	}

	@Override
	public PageBean getPage(Long page, Long pnum, String searchword) {
		Connection conn = ConnectionUtil.getConnection();
		QueryRunner runner = new QueryRunner();
		PageBean p = new PageBean(page, pnum, 0l);
		try {
			Long count = runner
					.query(conn,
							"select count(id) as count from document where title like ? ",
							new ScalarHandler<Long>(), "%" + searchword + "%");
			p.setCount(count);

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}
		return p;
	}

	@Override
	public boolean convert(Long ID) {
		Connection conn = ConnectionUtil.getConnection();
		QueryRunner runner = new QueryRunner();
		String docurl = null;
		try {
			Object[] objects = runner.query(conn,
					"select dir from  doc_dir where `id`=? and `type`!=?",
					new ArrayHandler(), ID, "pdf");
			String save_path_base = OptionUtil.getOption("opload_filePath");
			docurl = objects[0].toString();
			File file = new File(save_path_base + File.separator + docurl);
			File to = new File(file.getParent() + File.separator + ID + ".pdf");
			converter.convert(file, to);
			SimpleDateFormat dateformat = new SimpleDateFormat("yyyy/MM/dd");
			final String logoPathDir = "files/" + dateformat.format(new Date());
			runner.update(conn, "insert into doc_dir values(?,?,?)", ID, "pdf",
					logoPathDir + File.separator + ID + ".pdf");
			return true;

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}
		return false;
	}

	@Override
	public boolean isConvert(Long ID) {
		Connection conn = ConnectionUtil.getConnection();
		QueryRunner runner = new QueryRunner();

		Object[] obj;
		try {
			obj = runner.query(conn,
					"select dir from doc_dir where ID=? and type='pdf'",
					new ArrayHandler(), ID);
			if (obj != null && obj.length == 1) {
				return true;
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}

		return false;
	}

	@Override
	public boolean shenheAll(Integer zhuangtai) {
		Connection conn = ConnectionUtil.getConnection();
		QueryRunner runner = new QueryRunner();
		try {
			int i = 0;

			i += runner.update(conn, "update document set shenhe=?", zhuangtai);
			if (i > 0)
				return true;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}

		return false;
	}

	@Override
	public boolean update(Long docId, String docname, Integer cate,
			Integer roleid) {
		Connection conn = ConnectionUtil.getConnection();
		QueryRunner runner = new QueryRunner();
		try {
			int i = 0;

			i += runner.update(conn,
					"update document set title=?,cate=?,roleid=? where id=?",
					docname, cate, roleid, docId);
			if (i > 0)
				return true;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}

		return false;
	}

	@Override
	public void reIndexAll() throws SQLException, IOException,
			ClassNotFoundException {
		// 删除所有索引
		luceneIndexService.deleteAll();
		// 将所有文档标识为未索引
		Connection conn = ConnectionUtil.getConnection();
		QueryRunner runner = new QueryRunner();
		runner.update(conn, "update document set indexed=0");
		// 索引所有未索引的文档
		indexAll();

	}

	@Override
	public Long getIndexNum() {
		Connection conn = ConnectionUtil.getConnection();
		QueryRunner runner = new QueryRunner();
		try {
			return runner.query(conn,
					"SELECT count(id) from document where indexed=1",
					new ScalarHandler<Long>());

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}
		return null;
	}
}
